package no.ntnu.idi.deid.decision.validators;

import no.ntnu.idi.deid.documentunits.Token;

public class PersonNumberValidator {

	private PersonNumberValidator() {

	}

	public static boolean isTokenValidPNR(String str) {
		String result = str.replaceAll("[^0-9]", "");
		if(result.length() != 11) {
			return false;
		}
		String date = result.substring(0, 6);
		String DnumberDate = ((int)date.charAt(0)-4)+date.substring(1);
		String HnumberDate = date.substring(0,1)+((int)date.charAt(2)-4)+date.substring(3);
				
		String individualNumbers = result.substring(6, 9);
		int controlNumber1 = Integer.parseInt(result.substring(9, 10));
		int controlNumber2 = Integer.parseInt(result.substring(10));
		if (!(DateValidator.isValidPNRDateFormat(date) || DateValidator.isValidPNRDateFormat(DnumberDate) || DateValidator.isValidPNRDateFormat(HnumberDate))
				|| !isNumber(individualNumbers) ) {
			return false;
		}
		
		
		int[] intArray = convertCharToIntArray(result);
		int[] intArray2 = convertCharToIntArray(result);
		intArray2[0] = intArray[0]+4;
		int[] intArray3 = convertCharToIntArray(result);
		intArray3[2] = intArray[2]+4;
		int pnrcn1 = calculateControlNumber1(intArray);
		int pnrcn2 = calculateControlNumber2(intArray);
		int dnumbercn1 = calculateControlNumber1(intArray2);
		int dnumbercn2 = calculateControlNumber2(intArray2);
		int hnumbercn1 = calculateControlNumber1(intArray3);
		int hnumbercn2 = calculateControlNumber2(intArray3);
		if (!((pnrcn1 == controlNumber1 &&	pnrcn2 == controlNumber2)||
			(dnumbercn1 == controlNumber1 &&	dnumbercn2 == controlNumber2) ||
			(hnumbercn1 == controlNumber1 &&	hnumbercn2 == controlNumber2))) {
			return false;
		}
		return true;
	}
	
	public static int calculateControlNumber1(int[] numbers) {
		int cn1 = -1;
		if(numbers.length == 11) {
			cn1 = 11 - ((3 * numbers[0] + 7 * numbers[1] + 6 * numbers[2]
					+ numbers[3] + 8 * numbers[4] + 9 * numbers[5] + 4
					* numbers[6] + 5 * numbers[7] + 2 * numbers[8]) % 11);
			if(cn1 == 11) {
				cn1= 0;
			}
		}
		return cn1;
	}
	
	public static int calculateControlNumber2(int[] numbers) {
		int cn2 = -1;
		if(numbers.length == 11) {
			 cn2 = 11 - ((5 * numbers[0] + 4 * numbers[1] + 3 * numbers[2]
					+ 2 * numbers[3] + 7 * numbers[4] + 6 * numbers[5] + 5
					* numbers[6] + 4 * numbers[7] + 3 * numbers[8] + 2 * numbers[9]) % 11);
			if(cn2 == 11) {
				cn2= 0;
			}
		}
		return cn2;
	}
	
	
	public static boolean isTokenValidPNR(Token token) {
		return isTokenValidPNR(token.getStripped());
		
	}
	public static boolean checkTwoTokensForValidPNR(Token firstToken,Token secondToken) {
		String[] dateList = firstToken.getStripped().split("\\.");
		String formatedFirstString = firstToken.getStripped();
		if(dateList.length == 3) {
			if(dateList[2].length() == 4) {
				formatedFirstString = dateList[0]+dateList[1]+dateList[2].substring(2);
			}
		}
		return isTokenValidPNR(formatedFirstString+secondToken.getStripped());
	}

	private static int[] convertCharToIntArray(String str) {
		int[] returnArray = new int[str.length()];
		for (int i = 0; i < str.length(); i++) {
			returnArray[i] = Character.getNumericValue(str.charAt(i));
		}
		return returnArray;
	}

	private static boolean isNumber(String str) {
		try {
			Integer.parseInt(str);
		} catch (NumberFormatException e) {
			e.printStackTrace();
			return false;
		}
		return true;
	}
}
